package com.daxue002.attribute;

import com.daxue002.util.AttributeType;
import com.daxue002.util.Utility;
import com.daxue002.util.UtilityException;

public abstract class MessageAttribute implements MessageAttributeInterface {
	AttributeType type;

	public MessageAttribute() {
	}

	public MessageAttribute(AttributeType type) {
		setType(type);
	}

	public void setType(AttributeType type) {
		this.type = type;
	}

	public AttributeType getType() {
		return type;
	}

	public static int typeToInteger(AttributeType type) {
		if (type == AttributeType.MappedAddress)
			return MAPPEDADDRESS;
		if (type == AttributeType.ResponseAddress)
			return RESPONSEADDRESS;
		if (type == AttributeType.ChangeRequest)
			return CHANGEREQUEST;
		if (type == AttributeType.SourceAddress)
			return SOURCEADDRESS;
		if (type == AttributeType.ChangedAddress)
			return CHANGEDADDRESS;
		if (type == AttributeType.Username)
			return USERNAME;
		if (type == AttributeType.Password)
			return PASSWORD;
		if (type == AttributeType.MessageIntegrity)
			return MESSAGEINTEGRITY;
		if (type == AttributeType.ErrorCode)
			return ERRORCODE;
		if (type == AttributeType.UnknownAttribute)
			return UNKNOWNATTRIBUTE;
		if (type == AttributeType.ReflectedFrom)
			return REFLECTEDFROM;
		if (type == AttributeType.Dummy)
			return DUMMY;
		return -1;
	}

	public static AttributeType intToType(long type) {
		if (type == MAPPEDADDRESS)
			return AttributeType.MappedAddress;
		if (type == RESPONSEADDRESS)
			return AttributeType.ResponseAddress;
		if (type == CHANGEREQUEST)
			return AttributeType.ChangeRequest;
		if (type == SOURCEADDRESS)
			return AttributeType.SourceAddress;
		if (type == CHANGEDADDRESS)
			return AttributeType.ChangedAddress;
		if (type == USERNAME)
			return AttributeType.Username;
		if (type == PASSWORD)
			return AttributeType.Password;
		if (type == MESSAGEINTEGRITY)
			return AttributeType.MessageIntegrity;
		if (type == ERRORCODE)
			return AttributeType.ErrorCode;
		if (type == UNKNOWNATTRIBUTE)
			return AttributeType.UnknownAttribute;
		if (type == REFLECTEDFROM)
			return AttributeType.ReflectedFrom;
		if (type == DUMMY)
			return AttributeType.Dummy;
		return null;
	}

	abstract public byte[] getBytes() throws UtilityException;

	// abstract public MessageAttribute parse(byte[] data) throws
	// MessageAttributeParsingException;

	public int getLength() throws UtilityException {
		int length = getBytes().length;
		return length;
	}

	public static MessageAttribute parseCommonHeader(byte[] data)
			throws MessageAttributeParsingException {
		try {
			byte[] typeArray = new byte[2];
			System.arraycopy(data, 0, typeArray, 0, 2);
			int type = Utility.twoBytesToInteger(typeArray);
			byte[] lengthArray = new byte[2];
			System.arraycopy(data, 2, lengthArray, 0, 2);
			int lengthValue = Utility.twoBytesToInteger(lengthArray);
			byte[] valueArray = new byte[lengthValue];
			System.arraycopy(data, 4, valueArray, 0, lengthValue);
			MessageAttribute ma;
			switch (type) {
			case MAPPEDADDRESS:
				ma = MappedAddress.parse(valueArray);
				break;
			case RESPONSEADDRESS:
				ma = ResponseAddress.parse(valueArray);
				break;
			case CHANGEREQUEST:
				ma = ChangeRequest.parse(valueArray);
				break;
			case SOURCEADDRESS:
				ma = SourceAddress.parse(valueArray);
				break;
			case CHANGEDADDRESS:
				ma = ChangedAddress.parse(valueArray);
				break;
			case USERNAME:
				ma = Username.parse(valueArray);
				break;
			case PASSWORD:
				ma = Password.parse(valueArray);
				break;
			case MESSAGEINTEGRITY:
				ma = MessageIntegrity.parse(valueArray);
				break;
			case ERRORCODE:
				ma = ErrorCode.parse(valueArray);
				break;
			case UNKNOWNATTRIBUTE:
				ma = UnknownAttribute.parse(valueArray);
				break;
			case REFLECTEDFROM:
				ma = ReflectedFrom.parse(valueArray);
				break;
			default:
				if (type <= 0x7fff) {
					throw new UnknownMessageAttributeException("Unkown mandatory message attribute",intToType(type));
				} else {
					System.out.println("MessageAttribute with type " + type+ " unkown.");
					ma = Dummy.parse(valueArray);
					break;
				}
			}
			return ma;
		} catch (UtilityException ue) {
			throw new MessageAttributeParsingException("Parsing error");
		}
	}
}
